package com.m3958.firstgwt.server.servlet;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import redis.clients.jedis.Jedis;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.m3958.firstgwt.server.service.AppUtilService;
import com.m3958.firstgwt.server.service.FourOFourService;
import com.m3958.firstgwt.server.service.JedisPoolService;
import com.m3958.firstgwt.server.service.RequestScopeObjectService;
import com.m3958.firstgwt.server.service.WebFrontUrlParser;
import com.m3958.firstgwt.server.types.CharactSetName;
import com.m3958.firstgwt.server.utils.StringUtils;

import freemarker.template.Template;
import freemarker.template.TemplateException;


@Singleton
public class WebFrontServlet extends HttpServlet{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Inject
	private Injector injector;
	
	@Inject
	private AppUtilService autils;
	
	@Inject
	protected com.google.inject.Provider<EntityManager> emp;
	
	@Inject
	private JedisPoolService jpservice;
	
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		RequestScopeObjectService rso = injector.getInstance(RequestScopeObjectService.class);
		WebFrontUrlParser wfup = null;
		try {
			wfup = injector.getInstance(WebFrontUrlParser.class);
		} catch (Exception e1) {
			e1.printStackTrace();
			return;
		}
		
		
		
		try {
			if(!rso.getRequestWebHost().isAudit()){
				res.setContentType("text/html; charset=UTF-8");   
				res.setCharacterEncoding("UTF-8");
				Writer w = res.getWriter();
				w.write("此域名尚未经管理员审核，请联系管理员。奉化市诗篇网络科技有限公司，jianglibo@gmail.com");
				w.close();
			}
			
			if(rso.getRequestWebSite().isStop()){
				res.setContentType("text/html; charset=UTF-8");   
				res.setCharacterEncoding("UTF-8");
				Writer w = res.getWriter();
				if(wfup.getMaintenceFile() != null ){
					Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(wfup.getMaintenceFile()),CharactSetName.UTF_8));
			        int numRead=0;
			        char[] buf = new char[1024];
			        while((numRead=reader.read(buf)) != -1){
			        	w.write(buf, 0, numRead);
			        }
			        reader.close();
			        w.close();
			        return;
				}
				w.write("网站维护中.......，请稍候再来访问！");
				w.close();
				return;
			}
			
			
			
			File f = wfup.getNoneFtlFile();
			if(f != null && f.isFile()){
				autils.sendSiteFile(req, res, f, getServletContext().getMimeType(f.getAbsolutePath()));
			    return;
			}
		} catch (Exception e1) {
			res.setContentType("text/html; charset=UTF-8");   
			res.setCharacterEncoding("UTF-8");
			Writer w = res.getWriter();
			w.write("该域名没有对应的网站！");
			w.close();
			return;
		}
		
		if(rso.getRequestWebHost() == null){
			return;
		}
		Template template = null;
		try {
			template = wfup.getTpl();
		} catch (FileNotFoundException e1) {}
		
		if(template == null){
			injector.getInstance(FourOFourService.class).send404();
			return;
		}
		
		res.setContentType("text/html; charset=UTF-8");   
		res.setCharacterEncoding("UTF-8");
		String content = null;
		String etag = UUID.randomUUID().toString();
		PrintWriter writer = res.getWriter();
		try {
			StringWriter sWriter = new StringWriter();
			Map<String, Object> rm = wfup.getRootModel();
			rm.put("tplname", template.getName());
			template.process(rm, sWriter);
			content = sWriter.toString();
			res.setContentLength(content.getBytes("UTF8").length);
		} catch (TemplateException e) {
			e.printStackTrace(writer);
			return;
		}
		if(content == null || content.isEmpty()){
			res.setStatus(HttpServletResponse.SC_NO_CONTENT);
			return;
		}
		
		content = filterContent(content);
		
		res.setHeader("Etag", etag);
		writer.write(content);
		writer.close();
		if(rso.getRequestWebSite().isCacheEnable())
			saveCacheCopy(req,wfup,rso,content,etag);
	}

	private String filterContent(String content) {
		return content;
	}

	
	private void saveCacheCopy(HttpServletRequest req,WebFrontUrlParser wfup,RequestScopeObjectService rso,String content,String etag){
		Jedis jd = jpservice.getInstance(); 
		try {
			String ouri = (String) req.getAttribute("origin_ruri");
			String rurl = StringUtils.getCacheString(ouri,req.getQueryString());
			int siteId = rso.getRequestWebSite().getId();
			String oldEtag = req.getHeader("If-None-Match");
			Map<String, String> urlCacheMap = new HashMap<String, String>();
			urlCacheMap.put("etag", etag);
			urlCacheMap.put("content", content);
			jd.hmset(rurl, urlCacheMap);
			jd.set(etag, rurl);
			if(oldEtag != null)jd.del(oldEtag);
			String ob2etag = rso.getRequestWebSite().getId() + "," +  wfup.getObName() + "," + wfup.getObid();
			//(siteId)7878,article,72828
			jd.set(ob2etag,etag);
			
			jd.rpush("site:" + siteId, etag);//这里包含了所有的cache条目。
			jd.rpush("site:" + siteId, ob2etag);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jpservice.putBack(jd);
		}
	}
}
